You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When we do Commit on the trie when parents-of-leafs are encountered, we do two things:
call db.insert, which can be a fairly heavy operation, and
call the onleaf function for the leafs. This can also be somewhat heavy.
This PR splits this up, so that we can have one dedicated goroutine which handles the insertion and callbacks, and the main trie-walker can concentrate on iterating the trie.
Since the order of events (inserts and callback invocation) is unchanged by this PR, I don't think this has any buggy side-effects.
Here are the benchmark results:
name old time/op new time/op delta
CommitAfterHash/no-onleaf-6 5.10µs ±14% 4.28µs ± 8% -16.06% (p=0.000 n=10+9)
CommitAfterHash/with-onleaf-6 6.77µs ±19% 5.44µs ±18% -19.71% (p=0.000 n=10+10)
name old alloc/op new alloc/op delta
CommitAfterHash/no-onleaf-6 1.79kB ± 3% 1.94kB ± 5% +8.65% (p=0.000 n=10+10)
CommitAfterHash/with-onleaf-6 2.18kB ± 2% 2.22kB ± 2% +1.81% (p=0.004 n=10+10)
name old allocs/op new allocs/op delta
CommitAfterHash/no-onleaf-6 11.0 ± 0% 13.0 ± 0% +18.18% (p=0.000 n=10+10)
CommitAfterHash/with-onleaf-6 18.3 ± 4% 20.0 ± 0% +9.29% (p=0.000 n=10+10)
As can be expected, if there's an onleaf function provided, the gains are higher 20%, compared to 16% if there is no onleaf.
The benchmarks are pretty synthetic, though, and I imagine that there is a lot more work done in the insert section on a live node.
This PR should work pretty nicely even pre-byzantium, I'd guess.
The actual implementation can surely be cleaned up a bit, particularly the hack in trie.go could be made a bit more elegant.
The channel-based Commit is slower for trie sizes of <1000 items, so it would be good to retain the existing non-channel-based Commit for smaller tries. Either by having a measure of the number of changes in the trie (adding a counter to Update) or simply use a different method when invoking account commit versus storage commit.
Full sync in progress, it's just passed byzantium at 4.37M.
The exp machine is, I believe, a bit slower than master, and the exp is a bit behind in terms of blocks (seems to be about ten minutes). However, looking at the account commit chart, it seems that this PR is a couple of of milliseconds (or, maybe 20-25%) faster than master per block.
This PR hit byzantium about 5 minutes after master. After byzantium (4.37M), it started inching closer to master, and around block 4.822M it overtook it.
This chart shows the account commit:
During the high-intensity periods after byz, master peaks at 26ms , while this one peaks at 16ms.
Here's the last two days:
(OBS: notice that although they look identical, the y-axis are differently labeled -- the experimental is considerably faster on account commit)
From block ~4.56M to 6.02M. Experimental leads by about 10 minutes at the end.
After about 5 days of sync, the experimental is ahead with about 35 minutes. They're at block 7.6M, and I'm about to replace the images with another experiment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When we do
Commiton the trie when parents-of-leafs are encountered, we do two things:db.insert, which can be a fairly heavy operation, andonleaffunction for the leafs. This can also be somewhat heavy.This PR splits this up, so that we can have one dedicated goroutine which handles the insertion and callbacks, and the main trie-walker can concentrate on iterating the trie.
Since the order of events (inserts and callback invocation) is unchanged by this PR, I don't think this has any buggy side-effects.
Here are the benchmark results:
As can be expected, if there's an
onleaffunction provided, the gains are higher20%, compared to16%if there is noonleaf.The benchmarks are pretty synthetic, though, and I imagine that there is a lot more work done in the
insertsection on a live node.This PR should work pretty nicely even pre-byzantium, I'd guess.
The actual implementation can surely be cleaned up a bit, particularly the hack in
trie.gocould be made a bit more elegant.